﻿/*
 * Data.cs
 * 
 * Copyright (C) 2011 Elena Shishkina
 * 
 * This file is part of ServerInventory.
 * 
 * ServerInventory is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ServerInventory is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ServerInventory.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;

namespace ServerInventory
{
    public abstract class Data
    {
        protected string server;
        protected string user;
        protected string password;
        protected string dbname;

        public delegate void TakeStringDelegate(string str);
        public delegate string GetParamDelegate(string name);
        public delegate void SetHeaderDelegate(string name, string value);
        protected TakeStringDelegate writer;
        protected GetParamDelegate param;

        public Data(string server, string user, string password, string dbname)
        {
            this.server = server;
            this.user = user;
            this.password = password;
            this.dbname = dbname;
        }

        public Data() {
            writer = (x) => { Console.WriteLine(x); };
            param = (x) => { return ""; };
        }

        public void Init(string server, string user, string password, string dbname, TakeStringDelegate writer, GetParamDelegate param)
        {
            this.server = server;
            this.user = user;
            this.password = password;
            this.dbname = dbname;
            this.writer = writer;
            this.param = param;
        }

        protected SqlConnection DbConnect()
        {
            var str = new SqlConnectionStringBuilder();
            str.DataSource = server;
            str.UserID = user;
            str.Password = password;
            str.InitialCatalog = dbname;
            var conn = new SqlConnection(str.ToString());
            conn.Open();
            return conn;
        }

        public void ToJson(SqlCommand cmd)
        {
            var items = new List<string>();
            using (var rd = cmd.ExecuteReader())
            {

                while (rd.Read())
                {
                    var fields = new List<string>();
                    for (var i = 0; i < rd.FieldCount; i++)
                    {
                        var value = rd.IsDBNull(i) ? "" : rd[i].ToString();
                        if (value.Contains("\"")) value = value.Replace("\"", "\\\"");
                        fields.Add(String.Format(@"""{0}"":""{1}""", rd.GetName(i), value));
                    }
                    items.Add("{" + string.Join(",", fields.ToArray()) + "}");
                }

            }
            if (writer != null) writer("[" + string.Join(",", items.ToArray()) + "]");
        }

        public void ToJson()
        {
            if (writer != null) writer("{\"result\": \"RESULT_OK\"}");
        }

        protected void Result(string code)
        {
            if (writer != null) writer("{\"result\": \"" + code + "\"}");
        }

        protected void ResultOK()
        {
            Result("RESULT_OK");
        }

        protected int GetInt(string name)
        {
            var value = param(name);
            if (string.IsNullOrEmpty(value))
            {
                Result("ERROR_EMPTY_" + name.ToUpper());
                throw new ArgumentException("Empty " + name);
            }
            int val = 0;
            if (!int.TryParse(value, out val))
            {
                Result("ERROR_WRONG_" + name.ToUpper() + "_FORMAT");
                throw new ArgumentException("Wrong " + name + " format");
            }
            return val;
        }

        protected string GetString(string name)
        {
            return param(name);
        }

        abstract public void Process();

        abstract public void Headers(SetHeaderDelegate callback);
    }
}